package com.yaowk.platform.controller;

import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.kit.JMap;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.ActiveRecordException;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.activerecord.tx.TxConfig;
import com.yaowk.authc.Kit.PasswordKit;
import com.yaowk.authc.model.Permission;
import com.yaowk.authc.model.Platform;
import com.yaowk.authc.model.User;
import com.yaowk.authc.model.UserPermission;
import com.yaowk.common.kit.Constant;
import com.yaowk.common.kit.I18nKit;
import com.yaowk.common.kit.ResultKit;
import com.yaowk.common.validator.RequiredIdValidator;
import com.yaowk.system.model.Module;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;

import java.util.*;

/**
 * 管理员管理
 *
 * @authc yaowk
 * 2017/5/3
 */
@TxConfig(Constant.AUTHC_MODULE)
public class AdminController extends Controller {

    /**
     * 查询平台管理员列表
     *
     * @param id|平台id|Integer|必填
     * @title 查询平台管理员列表
     */
    @Before(RequiredIdValidator.class)
    @RequiresPermissions("platform:read")
    public void list() {
        Integer id = getParaToInt("id");
        List<User> userList = User.dao.findByPlatformIdAndType(id, 3);
        renderJson(ResultKit.success(userList));
    }

    /**
     * 查询管理员信息
     *
     * @param id|管理员id|Integer|必填
     * @title 查询管理员信息
     */
    @Before(RequiredIdValidator.class)
    @RequiresPermissions("platform:read")
    public void info() {
        User user = User.dao.findById(getParaToInt("id"));
        user.setPassword(null);
        List<Permission> permissionList = Permission.dao.findAll();
        List<UserPermission> userPermissionList = UserPermission.dao.findByUserId(user.getId());
        List<Map<String, Object>> permissionResult = new ArrayList<>();
        Set<Integer> checkedPermissions = new HashSet<>();
        for (UserPermission userPermission : userPermissionList) {
            checkedPermissions.add(userPermission.getPermissionId());
        }
        for (Permission permission : permissionList) {
            JMap map = JMap.create().set("id", permission.getId()).set("name", permission.getName());
            if (checkedPermissions.contains(permission.getId())) {
                map.set("checked", true);
            }
            else {
                map.set("checked", false);
            }
            permissionResult.add(map);
        }
        JMap jMap = JMap.create().set("user", user).set("permission", permissionResult);
        renderJson(ResultKit.success(jMap));
    }


    /**
     * 添加管理员
     *
     * @param user_code|账户|String|必填
     * @param admin_password|总管理员密码|Integer|必填
     * @param password|密码|String|否
     * @param head|头像|String|否
     * @param name|用户名|String|否
     * @param permission_id|权限id|Integer|否
     * @title 添加管理员
     */
    @Before(Tx.class)
    @RequiresRoles("admin")
    @RequiresPermissions("platform:update")
    public void add() {
        User user = getModel(User.class, "", true);
        User loginUser = (User) SecurityUtils.getSubject().getPrincipal();
        user.setPlatformId(loginUser.getPlatformId());
        String adminPassword = getPara("admin_password");
        Platform platform = Platform.dao.findById(user.getPlatformId());

        // 验证管理员密码
        User admin = User.dao.findByPlatformIdAndType(platform.getId(), 4).get(0);
        AuthenticationToken token = new UsernamePasswordToken(admin.getUsername(), adminPassword);
        AuthenticationInfo info = new SimpleAuthenticationInfo(admin.getUsername(), admin.getPassword(), "");
        if (!PasswordKit.passwordMatcher.doCredentialsMatch(token, info)) {
            renderJson(ResultKit.fail(I18nKit.get("admin_password_fail", Constant.PLATFORM_MODULE, this)));
            return;
        }

        user.setUsername(platform.getSign() + user.getUserCode())
                .setPassword(PasswordKit.passwordService.encryptPassword(user.getPassword()))
                .setCreateTime(new Date())
                .setCreateUser(loginUser.getId())
                .setType(3);
        try {
            user.save();
        }
        catch (ActiveRecordException e) {
            if (e.getMessage().endsWith("'username_UNIQUE'")) {
                renderJson(ResultKit.fail(I18nKit.get("username_exist", Constant.AUTHC_MODULE, this)));
                return;
            }
            throw e;
        }

        // 插入权限关系
        Integer userId = user.getId();
        Object[] permissionIds = getParaValuesToInt("permission_id");
        if (StrKit.notNull(permissionIds)) {
            List<UserPermission> userPermissionList = new ArrayList<>();
            for (Object id : permissionIds) {
                UserPermission userPermission = new UserPermission();
                userPermission.setUserId(userId).setPermissionId((Integer) id);
                userPermissionList.add(userPermission);
            }
            Db.batchSave(userPermissionList, userPermissionList.size());
        }
        renderJson(ResultKit.success(this));
    }

    /**
     * 修改管理员信息
     *
     * @param id|管理员id|Integer|必填
     * @param admin_password|总管理员密码|String|必填
     * @param password|密码|String|否
     * @param head|头像|String|否
     * @param name|用户名|String|否
     * @param permission_id|权限id|Integer|否
     * @title 修改管理员信息
     */
    @Before({ RequiredIdValidator.class, Tx.class })
    @RequiresRoles("admin")
    @RequiresPermissions("platform:update")
    public void edit() {
        User user = getModel(User.class, "", true);
        Integer userId = user.getId();
        User old = User.dao.findById(userId);
        String adminPassword = getPara("admin_password");
        Platform platform = Platform.dao.findById(old.getPlatformId());

        // 验证管理员密码
        User admin = User.dao.findByPlatformIdAndType(platform.getId(), 4).get(0);
        AuthenticationToken token = new UsernamePasswordToken(admin.getUsername(), adminPassword);
        AuthenticationInfo info = new SimpleAuthenticationInfo(admin.getUsername(), admin.getPassword(), "");
        if (!PasswordKit.passwordMatcher.doCredentialsMatch(token, info)) {
            renderJson(ResultKit.fail(I18nKit.get("admin_password_fail", Constant.PLATFORM_MODULE, this)));
            return;
        }

        // 密码不为空，则更新密码
        if (StrKit.notBlank(user.getPassword())) {
            old.setPassword(PasswordKit.passwordService.encryptPassword(user.getPassword()));
        }
        old.setHead(user.getHead()).setName(user.getName()).update();

        // 先删除再插入权限关系
        UserPermission.dao.deleteByUserId(userId);
        Object[] permissionIds = getParaValuesToInt("permission_id");
        if (StrKit.notNull(permissionIds)) {
            List<UserPermission> userPermissionList = new ArrayList<>();
            for (Object id : permissionIds) {
                UserPermission userPermission = new UserPermission();
                userPermission.setUserId(userId).setPermissionId((Integer) id);
                userPermissionList.add(userPermission);
            }
            Db.batchSave(userPermissionList, userPermissionList.size());
        }
        renderJson(ResultKit.success(this));
    }

    /**
     * 删除管理员
     *
     * @param id|管理员id|Integer|必填
     * @title 删除管理员
     */
    @Before({ RequiredIdValidator.class, Tx.class })
    @RequiresRoles("admin")
    @RequiresPermissions("platform:update")
    public void remove() {
        Integer id = getParaToInt("id");
        UserPermission.dao.deleteByUserId(id);
        User.dao.deleteById(id);
        renderJson(ResultKit.success(this));
    }

    /**
     * 获取权限列表
     *
     * @title 获取权限列表
     */
//    @RequiresRoles("admin")
//    @RequiresPermissions("platform:update")
    public void permissionList() {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        List<Module> moduleList = Module.dao.findByPlatformId(user.getPlatformId());
        List<String> moduleTypes = new ArrayList<>();
        for (Module module : moduleList) {
            if (module.getOpen() == 1) {
                moduleTypes.add(module.getType());
            }
        }

        List<Permission> permissionList = Permission.dao.findAll();
        List<Permission> result = new ArrayList<>();
        for (Permission permission : permissionList) {
            String[] ps = permission.getSign().split(":");
            if (moduleTypes.contains(ps[0])) {
                result.add(permission);
            }
        }

        renderJson(ResultKit.success(result));

    }
}
